﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Consul;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Hosting;

namespace Conference.Common.Consul
{
    public static class AppBuilderExtensions
    {
        public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IHostApplicationLifetime lifetime,
            ConsulServiceEntity serviceEntity)
        {
            var consulClient = new ConsulClient(x =>
                x.Address = new Uri($"http://{serviceEntity.ConsulIP}:{serviceEntity.ConsulPort}")); //请求注册的 Consul 地址
            var httpCheck = new AgentServiceCheck()
            {
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5), //服务启动多久后注册
                Interval = TimeSpan.FromSeconds(10), //健康检查时间间隔，或者称为心跳间隔
                HTTP = $"http://localhost:5000/api/HealthClick", //健康检查地址
                //Timeout = TimeSpan.FromSeconds(5)
            };
            if (!(app.Properties["server.Features"] is FeatureCollection features))
                return app;
            var addresses = features.Get<IServerAddressesFeature>();
            if (addresses != null)
            {
                var address = addresses.Addresses.First();
                var uri = new Uri(address);
                // Register service with consul
                var registration = new AgentServiceRegistration()
                {
                    Checks = new[] { httpCheck },
                    ID = "ConsulId",
                    Name = serviceEntity.ServiceName,
                    Address = serviceEntity.IP,
                    Port = uri.Port,
                    Tags = new[] { $"unprefixed-/{serviceEntity.ServiceName}" } //添加 urlprefix-/servicename 格式的 tag 标签，以便 Fabio 识别
                };

                consulClient.Agent.ServiceRegister(registration).Wait(); //服务启动时注册，内部实现其实就是使用 Consul API 进行注册（HttpClient发起）
                lifetime.ApplicationStopping.Register(() =>
                {
                    consulClient.Agent.ServiceDeregister(registration.ID).Wait(); //服务停止时取消注册
                });
            }
            return app;
        }
    }

}
